package com.weishenai.customerassistant.controller;

import cn.hutool.core.util.ZipUtil;
import com.weishenai.customerassistant.common.Result;
import com.weishenai.customerassistant.entity.MetersResult;
import com.weishenai.customerassistant.service.MetersResultsService;
import com.weishenai.customerassistant.service.QrCodeService;
import com.weishenai.customerassistant.utils.FileUtil;
import com.weishenai.customerassistant.utils.MyExcelUtil;
import com.weishenai.customerassistant.utils.UniqueIdUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

@Api(tags = "管理系统_文件操作")
@RestController
@RequestMapping("/file")
@Slf4j
public class FileController extends BaseController{

    @Autowired
    private MyExcelUtil myExcelUtil;
    @Autowired
    private MetersResultsService resultsService;
    @Value("${file.staticExcelDir}")
    private String staticExelDir;
    @Value("${file.imageSavePath}")
    private String fileSavePath;
    @Value("${file.materialsExcelOut}")
    private String excelOutUrl;
    @Autowired
    private MetersResultsService metersResultsService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Value("${file.materialsExcelOut}")
    private String outBaseUrl;
    @Autowired
    private QrCodeService qrCodeService;
    /**
     * 时间格式化
     */
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");// 格式化时间中间不能有空格

    public void download(File file, HttpServletResponse response) {
        try {
            // 获取文件名
            String filename = file.getName();
            // 获取文件后缀名
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }


    public void download(File file, String ad, HttpServletResponse response) {
        try {
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");//设置编码格式
            response.setHeader("Content-Disposition", "attachment;filename=" + filename + "");
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream;charset=UTF-8");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    @ApiOperation("下载Excel")
    @ApiImplicitParam(name = "fileName", value = "常用资源的文件名")
    @GetMapping("/downloadExcelFile/{fileName}")
    private Object downloadExcelFile(@PathVariable(name = "fileName") String fileName, HttpServletResponse response) {
        String url = staticExelDir + fileName;
        File excelFile = new File(url);
        try {
            download(excelFile, response);
            return response;
        } catch (Exception e) {
            return Result.failed(e.getMessage());
        }
    }

    @ApiOperation("查询所有Excel")
    @GetMapping("/getAllExcelFile")
    private Object getAllExcelFile() {
        File file = new File(staticExelDir);
        File[] files = file.listFiles();
        if (files.length == 0) return Result.failed("失败");
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            list.add(files[i].getName());
        }
        return Result.success(list);
    }

    @ApiOperation("下载Word以后下载对应的Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "substation", value = "供电所的名字"),
            @ApiImplicitParam(name = "customer", value = "客户名称"),
            @ApiImplicitParam(name = "fileName", value = "要下载的文件名")
    })
    @GetMapping("/downloadExcel/{substation}/{customer}/{fileName}")
    public Object downloadExcelWithWord(HttpServletResponse response, @PathVariable("substation") String substation
            , @PathVariable("customer") String customer, @PathVariable("fileName") String fileName) {
        try {

            File file = myExcelUtil.createExcel(customer, substation, fileName, outBaseUrl);
            if (file == null || !file.exists())
                return Result.failed("文件名不正确！");
            else {
                download(file, response);
                file.delete();
                return response;
            }
        } catch (Exception e) {
            return Result.failed(e.getMessage());
        }
    }

    @ApiOperation("批量打包Excel")
    @GetMapping("/downloadExcel")
    public Object downloadExcelAll(HttpServletResponse response, Long[] ids) {
        String url = excelOutUrl + UniqueIdUtil.getResultId(redisTemplate, false) + "/";
        try {
            MetersResult metersResult = null;
            log.info("ids数组长度为：" + ids.length);
            for (int i = 0; i < ids.length; i++) {
                log.info("第" + i + "个id是：" + ids[i]);
                metersResult = metersResultsService.selectById(ids[i]);
                if (metersResult == null) return Result.failed("id有误！");
                File excelFile = myExcelUtil.createExcel(metersResult.getCustomerName(), metersResult.getSubstationName(), metersResult.getMaterialType(), url);
                log.info("文件名：" + excelFile.getName());
                if (excelFile == null || !excelFile.exists())
                    return Result.failed("文件名不正确！");
            }
            //移动好了之后开始打包
            File zip = ZipUtil.zip(url);
            log.info("压缩包路径" + zip.getPath());
            String newZipPath = FileUtil.FixFileName(zip.getPath(), "材料单压缩包");
            File newZip = new File(newZipPath);
            //下载
            download(newZip, response);
            //下载完成以后删除
            //删除原始zip
            zip.delete();
            //删除改名的zip
            newZip.delete();
            //删除没有压缩的原始数据
            FileUtil.deleteDir(new File(url));
        } catch (Exception e) {
            return Result.failed(e.getMessage());
        }
        return response;
    }

    @ApiOperation("依据信息生成二维码")
    @GetMapping("/getQRCode/{qrCodeInfo}")
    public Object getQRCode(@PathVariable("qrCodeInfo") String codeContent) {
        try {
            log.info("成功生成二维码！");
            return Result.success(qrCodeService.createdCodeToBase64(codeContent));
        } catch (Exception e) {
            log.error("发生错误， 错误信息是：{}！", e.getMessage());
            return Result.failed("失败");
        }
    }
}
